Skip to content

feat: Update OpenAI runners to implement Runner protocol returning RunnerResult#149

Open
jsonbailey wants to merge 2 commits intojb/aic-2388/managed-resultfrom
jb/aic-2388/openai-runner-protocol
Open

feat: Update OpenAI runners to implement Runner protocol returning RunnerResult#149
jsonbailey wants to merge 2 commits intojb/aic-2388/managed-resultfrom
jb/aic-2388/openai-runner-protocol

Conversation

@jsonbailey
Copy link
Copy Markdown
Contributor

@jsonbailey jsonbailey commented Apr 28, 2026

Summary

  • `OpenAIModelRunner` and `OpenAIAgentRunner` now formally inherit from the `Runner` protocol class.
  • `OpenAIModelRunner.run()` implements the unified `Runner` protocol; returns `RunnerResult` with `content`, `metrics`, `raw`, and `parsed` fields. Structured output is supported via the `output_type` parameter.
  • `OpenAIAgentRunner.run()` updated to return `RunnerResult`; populates `tool_calls` in `LDAIMetrics` from observed openai-agents `ToolCallItem`s.
  • Legacy `invoke_model()` and `invoke_structured_model()` removed — the deprecated type definitions (`ModelRunner`, `ModelResponse`, etc.) are kept in `server-ai` for provider CI compatibility until a cleanup PR removes them.

Stacking

Stacked on top of `jb/aic-2388/managed-result` (PR #148).

Test plan

  • `make test-openai` — all OpenAI provider tests pass
  • `make test` — all tests across server-ai, langchain, and openai packages pass

🤖 Generated with Claude Code


Note

Medium Risk
Medium risk because it changes the provider runner interface and result shape (e.g., run signatures and RunnerResult fields), which can break downstream integrations even though behavior is largely preserved.

Overview
Updates the OpenAI provider runners to the unified Runner protocol, replacing legacy AgentRunner/ModelRunner return types with RunnerResult (content, raw, optional parsed).

OpenAIModelRunner.run now accepts either a prompt string or LDMessage list and supports structured output via output_type (JSON schema), parsing JSON into RunnerResult.parsed when requested. OpenAIAgentRunner.run now returns RunnerResult and records observed tool invocations in LDAIMetrics.tool_calls by extracting tool call items from openai-agents run results.

Tests are updated to assert the new run() behavior and RunnerResult fields for both chat completions and structured output paths, and to reflect the agent runner’s new result shape.

Reviewed by Cursor Bugbot for commit 2878bda. Bugbot is set up for automated code reviews on this repo. Configure here.

@jsonbailey jsonbailey force-pushed the jb/aic-2388/managed-result branch from bd4cd68 to 45441da Compare April 29, 2026 13:14
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch from f1845b4 to 94f09ee Compare April 29, 2026 13:14
@jsonbailey jsonbailey force-pushed the jb/aic-2388/managed-result branch from 45441da to 27bcfc0 Compare April 29, 2026 13:18
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch from 94f09ee to 8463109 Compare April 29, 2026 13:19
@jsonbailey jsonbailey force-pushed the jb/aic-2388/managed-result branch from 27bcfc0 to ff47ec2 Compare April 29, 2026 13:22
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch 2 times, most recently from eacddee to 842e4e6 Compare April 29, 2026 13:46
@jsonbailey jsonbailey force-pushed the jb/aic-2388/managed-result branch from 2ea3384 to 369242d Compare April 29, 2026 13:56
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch from 842e4e6 to 4c95357 Compare April 29, 2026 13:56
@jsonbailey jsonbailey force-pushed the jb/aic-2388/managed-result branch from 369242d to b8d3fad Compare April 29, 2026 14:37
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch from 4c95357 to 3f6882c Compare April 29, 2026 14:38
@jsonbailey jsonbailey force-pushed the jb/aic-2388/managed-result branch from b8d3fad to 4e28ae6 Compare April 29, 2026 16:31
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch from 3f6882c to efeea93 Compare April 29, 2026 16:31


class OpenAIAgentRunner(AgentRunner):
class OpenAIAgentRunner:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should add the Runner protocol here vs stating it in the doc below

@@ -14,10 +14,15 @@

class OpenAIModelRunner(ModelRunner):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be switched to the Runner protocol.

@jsonbailey jsonbailey marked this pull request as ready for review April 29, 2026 16:31
@jsonbailey jsonbailey requested a review from a team as a code owner April 29, 2026 16:31
Comment thread packages/ai-providers/server-ai-openai/src/ldai_openai/openai_agent_runner.py Outdated
self._model_name = model_name
self._parameters = parameters

async def invoke_model(self, messages: List[LDMessage]) -> ModelResponse:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing deprecated adapters breaks backward compatibility with callers

Medium Severity

The PR description states "Legacy invoke_model() and invoke_structured_model() retained as deprecated adapters that delegate to run() for backward compatibility," but these methods are completely absent from OpenAIModelRunner. The SDK's ManagedModel.invoke() calls self._model_runner.invoke_model() directly without an isinstance check, and Judge.evaluate() calls self._model_runner.invoke_structured_model(). If an OpenAIModelRunner instance is used through either of these existing code paths, it will raise AttributeError at runtime.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit efeea93. Configure here.

@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch 3 times, most recently from 330acf1 to cd983aa Compare April 29, 2026 17:13
@jsonbailey jsonbailey force-pushed the jb/aic-2388/managed-result branch from 7352a34 to adfd9f0 Compare April 29, 2026 17:14
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch from cd983aa to 184be64 Compare April 29, 2026 17:14
@jsonbailey jsonbailey force-pushed the jb/aic-2388/managed-result branch from adfd9f0 to b4d15df Compare April 29, 2026 17:17
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch 4 times, most recently from 3556ba4 to b5f15b7 Compare April 29, 2026 21:07
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch 4 times, most recently from 9254ccc to d113d46 Compare April 30, 2026 14:20
jsonbailey and others added 2 commits April 30, 2026 09:42
…nnerResult

- OpenAIModelRunner.run() implements the unified Runner protocol; returns RunnerResult
  with content, metrics (LDAIMetrics), raw, and parsed fields. Structured output is
  supported via the output_type parameter.
- OpenAIAgentRunner.run() updated to return RunnerResult; populates tool_calls in
  LDAIMetrics from observed openai-agents ToolCallItems.
- Legacy invoke_model() and invoke_structured_model() retained as deprecated adapters
  that delegate to run() and wrap results into ModelResponse / StructuredResponse for
  backward compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nner

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jsonbailey jsonbailey force-pushed the jb/aic-2388/openai-runner-protocol branch from d113d46 to 2878bda Compare April 30, 2026 14:43
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2878bda. Configure here.

tool_calls = [
tool_name
for _agent_name, tool_name in get_tool_calls_from_run_items(result.new_items)
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent runner reports function names instead of config keys

Medium Severity

The tool_calls list in LDAIMetrics is populated with raw runtime names from get_tool_calls_from_run_items (which returns Python __name__ values for custom function tools), rather than the LD config key names. The graph runner correctly builds a _tool_name_map (mapping fn.__name__ → config key) and uses it when tracking tool calls. The agent runner lacks this mapping, so it reports e.g. my_weather_function instead of the config name get-weather. This is inconsistent with the graph runner and with the tracker's documented semantics ("List of tool keys that were invoked").

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2878bda. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant